package com.dyh.quickdemozwei.deliver;

import java.util.*;
import java.util.function.Function;

public class ManyManyReference   {
    Map<String, Set<String>> forwardMap = new HashMap<>();
    Map<String, Set<String>> reverseMap = new HashMap<>();

    public <T> void updateByAuto(List<T> datas, Function<T,String> tf,Function<T,String> tr){
        for (T data : datas) {
            forwardMap.computeIfAbsent(tf.apply(data),x->new HashSet<>())
                    .add(tr.apply(data));


            reverseMap.computeIfAbsent(tr.apply(data),x->new HashSet<>())
                    .add(tf.apply(data));


        }
    }


    public  void updateByAuto(String f,String r){

        forwardMap.computeIfAbsent(f,x->new HashSet<>())
                .add(r);

        reverseMap.computeIfAbsent(r,x->new HashSet<>())
                .add(f);


    }

    public ManyManyReference infer(OneOneReference other){
        ManyManyReference resultReference = new ManyManyReference();

        for (Map.Entry<String, Set<String>> entry : forwardMap.entrySet()) {
            entry.getValue().forEach(e->{
                String nv = other.getForward(e);
                if (nv!=null){
                    resultReference.updateByAuto(entry.getKey(),nv);
                }
            });
        }

        return resultReference;
    }


    public ManyManyReference infer(OneManyReference  other){
        ManyManyReference resultReference = new ManyManyReference();

        for (Map.Entry<String, Set<String>> entry : forwardMap.entrySet()) {
            entry.getValue().forEach(e->{
                Set<String> nv = other.getForward(e);
                if (nv!=null){
                    nv.forEach(x-> resultReference.updateByAuto(entry.getKey(),x));

                }
            });
        }

        return resultReference;
    }

    public ManyManyReference infer(ManyManyReference  other){
        ManyManyReference resultReference = new ManyManyReference();

        for (Map.Entry<String, Set<String>> entry : forwardMap.entrySet()) {
            entry.getValue().forEach(e->{
                Set<String> nv = other.getForward(e);
                if (nv!=null){
                    nv.forEach(x-> resultReference.updateByAuto(entry.getKey(),x));

                }
            });
        }

        return resultReference;
    }

    public Set<String> getForward(String k){
        return forwardMap.get(k);
    }

    public Set<String> getReverse(String k){
        return reverseMap.get(k);
    }

    public Map<String, Set<String>> getForwardMap() {
        return forwardMap;
    }

    public void setForwardMap(Map<String, Set<String>> forwardMap) {
        this.forwardMap = forwardMap;
    }

    public Map<String, Set<String>> getReverseMap() {
        return reverseMap;
    }

    public void setReverseMap(Map<String, Set<String>> reverseMap) {
        this.reverseMap = reverseMap;
    }
}

